<template>
  <el-dialog
    v-if="roleId !== -1"
    title="权限配置"
    :visible.sync="roleVisi"
    width="800px"
    top="10vh"
    :close-on-click-modal="false"
    :before-close="cancel"
  >
    <el-tabs v-model="activeName">
      <el-tab-pane label="菜单&操作权限" name="first">
        <el-table
          v-loading="loading"
          :data="tableData"
          highlight-current-row
          :span-method="objectSpanMethod"
          height="500"
          border
          :header-cell-style="headerCellStyle"
        >
          <el-table-column prop="firstMenu" label="一级菜单" width="150">
            <template slot-scope="{ row, $index }">
              <el-checkbox
                v-model="row.checkedFirstMenu"
                :label="row.firstMenu"
                @change="changeFirstMenu($index)"
              />
            </template>
          </el-table-column>
          <el-table-column prop="secondMenu" label="二级菜单" width="150">
            <template slot-scope="{ row, $index }">
              <el-checkbox
                v-if="row.secondMenu"
                v-model="row.checkedSecondMenu"
                :label="row.secondMenu"
                @change="changeSecondMenu($index)"
              />
            </template>
          </el-table-column>
          <el-table-column prop="operateList" label="操作">
            <template slot-scope="{ row, $index }">
              <span
                v-for="(operate, operateIndex) in row.operateList"
                :key="operateIndex"
                style="margin-right: 10px"
              >
                <el-checkbox
                  v-if="operate.name"
                  v-model="operate.isChecked"
                  :label="operate.name"
                  @change="changeOperateMenu($index, operateIndex)"
                />
              </span>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
    </el-tabs>

    <div slot="footer" class="dialog-footer">
      <el-button size="small" @click="cancel">取 消</el-button>
      <el-button v-loading="saveLoading" type="primary" size="small" @click="save">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
let childrenIndex = 0;
const lodash = require("lodash");

import {
  getNewItem, permSave
} from "@/api/auth";

export default {

  props: {
    opPermShow: {
      type: Boolean,
      default: false
    },
    roleId: {
      type: Number,
      default: -1
    }
  },
  data() {
    return {
      activeName: "first",
      saveLoading: false,
      roleVisi: false,
      loading: true,
      tableData: []
    };
  },
  watch: {
    opPermShow: {
      handler(val) {
        this.roleVisi = val;
        if (val) {
          this.init();
        }
      }
    }
  },
  mounted() {
    this.useEnter();
  },
  created() {
    this.init();
  },

  methods: {
    useEnter() {
      window.addEventListener("keydown", this.keyupSubmit, false);
      this.$once("hook:beforeDestroy", () => {
        window.removeEventListener("keydown", this.keyupSubmit, false);
      });
    },
    keyupSubmit(e) {
      if (e.keyCode === 13 && this.roleVisi) {
        this.save();
      }
    },
    headerCellStyle() {
      return {
        textAlign: "center"
      };
    },
    cancel() {
      this.roleVisi = false;
      this.$emit("update:opPermShow", false);
    },
    // 保存
    async save() {
      const permData = {
        roleId: this.roleId,
        menus: this.tableData
      };
      this.saveLoading = true;
      await permSave(permData);
      this.saveLoading = false;

      this.$emit("update:opPermShow", false);
      this.$emit("search");
      this.$message.success("操作成功");
    },
    // 获取菜单列表
    async init() {
      if (this.roleId === -1) {
        return;
      }
      const para = {
        roleId: this.roleId
      };
      this.loading = true;
      getNewItem(para).then(res => {
        this.loading = false;
        this.tableData = res.map(item => {
          if (item.operateList && item.operateList.length) {
            item.operateList = item.operateList.map(ele => {
              const { code, name, checked, id } = ele;
              return {
                name: name,
                code: code,
                isChecked: checked,
                id: id
              };
            });
          }
          return item;
        });
      });
    },
    // 合并单元格
    // columnIndex 列下标
    // row 行数据
    // column 列
    // rowIndex  行下标，不包含表头，从数据列开始
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        // 合并行
        if (childrenIndex > 1) {
          childrenIndex--;
          return {
            rowspan: 0,
            colspan: 0
          };
        } else {
          childrenIndex = row.children;
          return {
            rowspan: row.children > 0 ? row.children : 1,
            colspan: 1
          };
        }
      }
    },

    // 一级菜单值变化
    changeFirstMenu(index) {
      const val = this.tableData[index].checkedFirstMenu;
      const firstMenu = this.tableData[index].firstMenu;
      this.tableData = this.tableData?.map((item1, index1) => {
        if (item1.firstMenu === firstMenu) {
          return {
            ...item1,
            checkedFirstMenu: val,
            checkedSecondMenu: val,
            operateList:
              item1.operateList?.map(item2 => {
                return { ...item2, isChecked: val };
              }) || []
          };
        }
        return { ...item1 };
      });
    },
    // 二级菜单值变化
    changeSecondMenu(index) {
      const val = this.tableData[index].checkedSecondMenu;
      const firstMenu = this.tableData[index].firstMenu;
      const secondMenu = this.tableData[index].secondMenu;
      let flag = false;
      const indexItems = [];
      this.tableData = this.tableData?.map((item1, index1) => {
        // 点击的当前行
        if (item1.secondMenu === secondMenu) {
          if (!val) {
            indexItems.push({ index: index1, item: item1 });
          }
          if (item1.firstMenu === firstMenu && item1.checkedFirstMenu !== val) {
            return {
              ...item1,
              checkedFirstMenu: val,
              operateList:
                item1.operateList?.map(item2 => {
                  return { ...item2, isChecked: val };
                }) || []
            };
          }

          return {
            ...item1,
            operateList:
              item1.operateList?.map(item2 => {
                return { ...item2, isChecked: val };
              }) || []
          };
        } else if (item1.firstMenu === firstMenu) {
          // if(item1.checkedFirstMenu)
          // 当二级菜单为true时
          if (val) {
            // 判断一级菜单与它相等的数据 一级菜单有没有选，没有选则手动选上，否则不做处理
            if (!item1.checkedFirstMenu) {
              return {
                ...item1,
                checkedFirstMenu: val
              };
            }
            return { ...item1 };
          } else {
            // 当二级菜单为false时
            // 当与当前选择的行不同，但一级菜单相同，且二级菜单只为true
            if (index1 !== index && item1.checkedSecondMenu) {
              flag = true;
              indexItems.push({ index: index1, item: item1 });
            }
            return { ...item1 };
          }
        }
        return { ...item1 };
      });
      // 二级菜单全部取消，需要将对应一级菜单设置为false
      if (indexItems.length === 1) {
        const tempTableData = lodash.cloneDeep(this.tableData);
        tempTableData.forEach((item, index) => {
          if (indexItems[0].item.firstMenu === item.firstMenu) {
            this.$set(tempTableData, index, {
              ...item,
              checkedFirstMenu: false
            });
          }
        });
        this.tableData = lodash.cloneDeep(tempTableData);
      }
      // 二级菜单取消时控制一级菜单
      if (flag) {
        const tempTableData = lodash.cloneDeep(this.tableData);
        indexItems.forEach(item => {
          this.$set(tempTableData, item.index, {
            ...tempTableData[item.index],
            checkedFirstMenu: true
          });
        });
        this.tableData = lodash.cloneDeep(tempTableData);
      }
      this.$forceUpdate();
    },
    // 页面功能选择
    changeOperateMenu(index, operateIndex) {
      const val = this.tableData[index].operateList[operateIndex].isChecked;
      const firstMenu = this.tableData[index].firstMenu;
      const operateList = this.tableData[index].operateList;
      let flag = false;

      const indexItems = [];
      if (val) {
        // 按钮操作选为true
        const selectList = operateList.filter(
          operate => operate.isChecked === true
        );
        if (selectList.length === 1) {
          this.$set(this.tableData, index, {
            ...this.tableData[index],
            checkedSecondMenu: true
          });
          this.tableData = this.tableData.map(item1 => {
            if (firstMenu === item1.firstMenu) {
              return { ...item1, checkedFirstMenu: true };
            }
            return { ...item1 };
          });
        }
      } else {
        this.tableData.forEach((item1, index1) => {
          if (firstMenu === item1.firstMenu && item1.checkedSecondMenu) {
            flag = true;
            indexItems.push({ index: index1, item: item1 });
          }
        });
        // 二级菜单全部取消，需要将对应一级菜单设置为false
        if (indexItems.length === 0) {
          this.tableData = this.tableData.map(item1 => {
            if (firstMenu === item1.firstMenu) {
              return { ...item1, checkedFirstMenu: false };
            }
            return { ...item1 };
          });
        }
        // 对应一级菜单下只要有一个二级菜单被选中，就需要设置为true
        if (flag) {
          const tempTableData = lodash.cloneDeep(this.tableData);
          indexItems.forEach(item => {
            this.$set(tempTableData, item.index, {
              ...tempTableData[item.index],
              checkedFirstMenu: true
            });
          });
          this.tableData = lodash.cloneDeep(tempTableData);
        }
      }
    }
  }
};
</script>
